msg_tool\scripts\escude/
crypto.rs

1use crate::ext::io::*;
2use anyhow::Result;
3use rand::Rng;
4use std::io::{Read, Seek, Write};
5
6pub struct CryptoReader<T: Read + Seek> {
7    reader: T,
8    _key: u32,
9    max_pos: u32,
10}
11
12impl<T: Read + Seek> CryptoReader<T> {
13    pub fn new(mut reader: T) -> Result<Self> {
14        let _key = reader.peek_u32_at(0x8)?;
15        let mut s = CryptoReader {
16            reader,
17            _key,
18            max_pos: 0,
19        };
20        s.init()?;
21        Ok(s)
22    }
23
24    fn key(&mut self) -> u32 {
25        self._key ^= 0x65AC9365;
26        self._key ^= (((self._key >> 1) ^ self._key) >> 3) ^ (((self._key << 1) ^ self._key) << 3);
27        return self._key;
28    }
29
30    fn init(&mut self) -> Result<()> {
31        let _key = self._key;
32        self.max_pos = (self.reader.peek_u32_at(0xC)? ^ self.key()) * 12 + 0xC;
33        self._key = _key;
34        Ok(())
35    }
36}
37
38impl<T: Read + Seek> Read for CryptoReader<T> {
39    fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
40        let remaing = self.max_pos as usize + 0x8 - self.reader.stream_position()? as usize;
41        let count = buf.len().min(remaing);
42        let readed = self.reader.read(&mut buf[..count])?;
43        for i in 0..readed / 4 {
44            let val = u32::from_le_bytes(buf[i * 4..i * 4 + 4].try_into().map_err(|_| {
45                std::io::Error::new(
46                    std::io::ErrorKind::InvalidData,
47                    "Failed to convert slice to u32",
48                )
49            })?);
50            let decrypted = val ^ self.key();
51            buf[i * 4..i * 4 + 4].copy_from_slice(&decrypted.to_le_bytes());
52        }
53        Ok(readed)
54    }
55}
56
57pub struct CryptoWriter<T: Write + Seek> {
58    writer: T,
59    key: u32,
60    in_buffer: Vec<u8>,
61}
62
63impl<T: Write + Seek> CryptoWriter<T> {
64    pub fn new(mut writer: T) -> Result<Self> {
65        let mut rng = rand::rng();
66        let key = rng.random();
67        writer.write_u32(key)?;
68        Ok(Self {
69            writer,
70            key,
71            in_buffer: Vec::new(),
72        })
73    }
74
75    fn key(&mut self) -> u32 {
76        self.key ^= 0x65AC9365;
77        self.key ^= (((self.key >> 1) ^ self.key) >> 3) ^ (((self.key << 1) ^ self.key) << 3);
78        return self.key;
79    }
80}
81
82impl<T: Write + Seek> Write for CryptoWriter<T> {
83    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
84        self.in_buffer.extend_from_slice(buf);
85        while self.in_buffer.len() >= 4 {
86            let mut val = self.in_buffer.as_slice().read_u32()?;
87            val ^= self.key();
88            self.writer.write_u32(val)?;
89            self.in_buffer.drain(0..4);
90        }
91        Ok(buf.len())
92    }
93
94    fn flush(&mut self) -> std::io::Result<()> {
95        self.writer.flush()
96    }
97}